package com.tuku.picturesearch;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;

public class NetworkPictureFinder {
    private static final String TAG = "NetworkPictureFinder";
    private static final String BAIDU_API = "http://image.baidu.com/i?tn=baiduimagejson&width=&height=&";
    private int time_out = 5000;
    public List<Bitmap> bitmaps; 
    private List<String> urls;

    NetworkPictureFinder() {
        bitmaps = new LinkedList<Bitmap>();
        urls = new LinkedList<String>();
    }

   
    public void find(String keyword, int number, int pages) {
        Log.i(TAG, "find(" + keyword + ", " + number + ", " + pages + ") called");

        JSONObject obj = getJSON(keyword, number, pages);
        getUrl(obj);

        if(urls == null) {
            Log.e(TAG, "Cannot receive data from search engine");
            return;
        }

        bitmaps.clear();
        FetchThread thread = new FetchThread();
        thread.start();

        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private JSONObject getJSON(String keyword, int number, int pages) {
        Log.i(TAG, "getJSON called");

        JSONObject object = null;
        String request_url;
        InputStream input_stream;

        String encoded_word = null;
        try {
            encoded_word = URLEncoder.encode(keyword, "GB2312");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        request_url = BAIDU_API + "word=" + encoded_word + "&rn=" + number + "&pn=" + pages;
        Log.i(TAG, "request_url: " + request_url);

        try {
            URL url = new URL(request_url);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setConnectTimeout(time_out);
            conn.setReadTimeout(time_out);
            conn.setRequestMethod("GET");
            input_stream = conn.getInputStream();

            if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            
                byte[] data = readStream(input_stream);
                String json = new String(data);
                Log.e(TAG, "json data: " + json);
                object = new JSONObject(json);
                input_stream.close();
            }
            else
                Log.e(TAG, "Cannot connect to search engine");
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(object == null)
            Log.e(TAG, "Cannot receive JSON");

        return object;
    }

    private void getUrl(JSONObject object) {
        Log.i(TAG, "getUrl called");

        if(object == null)
            return;

        JSONArray data = object.optJSONArray("data");
        if(data == null)
        {
            Log.e(TAG, "Cannot find data section in JSON");
            return;
        }

        urls.clear();
        for(int i = 0; i < data.length(); ++i)
        {
            JSONObject data_object = data.optJSONObject(i);
            String obj_url = data_object.optString("objURL");
            if(obj_url != null && !obj_url.isEmpty())
            {
                urls.add(obj_url);
                Log.i(TAG, "find url: " + obj_url);
            }
        }

        if(urls.isEmpty())
            Log.e(TAG, "Cannot find image url from JSON");
    }

    public static byte[] readStream(InputStream inputStream) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;

        while ((len = inputStream.read(buffer)) != -1) {
            bout.write(buffer, 0, len);
        }

        bout.close();
        inputStream.close();

        return bout.toByteArray();
    }

    private class FetchThread extends Thread {

        @Override
        public void run() {
            Log.i(TAG, "fetch thread is running");
            InputStream input_stream = null;
            while (urls.size() > 0) {
                String url = urls.remove(0);
                Log.i(TAG, "Processing " + url);
                try {
                    URL file_url = new URL(url);
                    HttpURLConnection conn = (HttpURLConnection)file_url.openConnection();
                    conn.setConnectTimeout(time_out);
                    conn.setReadTimeout(time_out);
                    conn.setRequestMethod("GET");
                    input_stream = conn.getInputStream();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                bitmaps.add(BitmapFactory.decodeStream(input_stream));
                Log.i(TAG, "Download completed");
            }
        }
    }
}
